import mysql from 'mysql'
import { Models } from '../common/typings/model'
import dbConfig from '../config/dbConfig'
import { DataBaseFailed } from '../core/HttpException'
import { lineToHumpObject } from '../common/utils/utils'
class Mysql {
  // 创建连接池
  public static readonly pool = mysql.createPool({
    host: dbConfig.database.host,
    port: dbConfig.database.port,
    user: dbConfig.database.username,
    password: dbConfig.database.password,
    database: dbConfig.database.dbName,
    multipleStatements: true, // 运行执行多条语句
    connectionLimit: 60 * 60 * 1000,
    connectTimeout: 1000 * 60 * 60 * 1000,
    acquireTimeout: 60 * 60 * 1000,
    timeout: 1000 * 60 * 60 * 1000,
  })

  /*
   * 数据库增删改查
   * @param command 增删改查语句
   * @param value 对应的值
   */
  public static async command(command: string, value?: Array<any>): Promise<Models.Result> {
    try {
      return new Promise<Models.Result>((resolve, reject) => {
        this.pool.getConnection((error: mysql.MysqlError, connection: mysql.PoolConnection) => {
          // 如果连接出错, 抛出错误
          if (error) {
            const result: Models.MysqlError = {
              error,
              msg: '数据库连接出错' + ':' + error.message,
            }
            reject(result)
          }

          const callback: mysql.queryCallback = (err, results?: any, fields?: mysql.FieldInfo[]) => {
            connection.release()
            if (err) {
              const result: Models.MysqlError = {
                error: err,
                msg: err.sqlMessage || '数据库增删改查出错',
              }

              reject(result)
            } else {
              const result: Models.Result = {
                msg: 'ok',
                state: 1,
                // 将数据库里的字段, 由下划线更改为小驼峰
                results: results instanceof Array ? results.map(lineToHumpObject) : results,
                fields: fields || [],
              }
              resolve(result)
            }
          }
          // 执行mysql语句
          if (value) {
            this.pool.query(command, value, callback)
          } else {
            this.pool.query(command, callback)
          }
        })
      })
    } catch (err) {
      throw new DataBaseFailed()
    }
  }
}
export default Mysql
